/**
 * 逻辑命令助手
 * 
 * 职责：
 * 1. 为逻辑系统提供便捷的命令发送接口
 * 2. 封装常用的渲染命令
 * 3. 简化命令队列的使用
 * 4. 支持命令依赖关系
 * 
 * @author AI Assistant
 * @date 2025-11-26
 */

import { Vec3, Color } from "cc";
import { commandQueue, CommandType, CommandPriority } from "./CommandQueue";

/**
 * 命令选项接口
 */
export interface CommandOptions {
    /** 优先级 */
    priority?: CommandPriority;
    
    /** 依赖的命令 ID 列表 */
    dependencies?: string[];
    
    /** 执行回调 */
    onExecute?: (result: any) => void;
    
    /** 错误回调 */
    onError?: (error: Error) => void;
}

/**
 * 逻辑命令助手类
 * 在逻辑系统中使用，发送渲染命令
 */
export class LogicCommandHelper {
    // ========== 节点操作命令 ==========
    
    /**
     * 设置实体位置
     * @param entityId 实体 ID
     * @param x X 坐标
     * @param y Y 坐标
     * @param z Z 坐标（可选）
     * @param options 命令选项
     */
    static setPosition(
        entityId: number,
        x: number,
        y: number,
        z: number = 0,
        options?: CommandOptions
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_POSITION,
            entityId,
            { x, y, z },
            options?.priority || CommandPriority.NORMAL,
            {
                onExecute: options?.onExecute,
                onError: options?.onError
            },
            options?.dependencies
        );
    }
    
    /**
     * 设置实体位置（Vec3）
     */
    static setPositionVec3(
        entityId: number,
        position: Vec3,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_POSITION,
            entityId,
            position,
            priority
        );
    }
    
    /**
     * 设置实体旋转
     * @param entityId 实体 ID
     * @param x X 轴旋转
     * @param y Y 轴旋转
     * @param z Z 轴旋转
     * @param priority 优先级
     */
    static setRotation(
        entityId: number,
        x: number,
        y: number,
        z: number,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_ROTATION,
            entityId,
            { x, y, z },
            priority
        );
    }
    
    /**
     * 设置实体缩放
     * @param entityId 实体 ID
     * @param scale 缩放值（统一缩放）或 { x, y, z }
     * @param priority 优先级
     */
    static setScale(
        entityId: number,
        scale: number | { x: number; y: number; z?: number },
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_SCALE,
            entityId,
            scale,
            priority
        );
    }
    
    /**
     * 设置实体可见性
     * @param entityId 实体 ID
     * @param visible 是否可见
     * @param priority 优先级
     */
    static setVisible(
        entityId: number,
        visible: boolean,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_VISIBLE,
            entityId,
            { visible },
            priority
        );
    }
    
    /**
     * 显示实体
     */
    static show(entityId: number): string {
        return this.setVisible(entityId, true);
    }
    
    /**
     * 隐藏实体
     */
    static hide(entityId: number): string {
        return this.setVisible(entityId, false);
    }
    
    /**
     * 设置实体激活状态
     * @param entityId 实体 ID
     * @param active 是否激活
     * @param priority 优先级
     */
    static setActive(
        entityId: number,
        active: boolean,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_ACTIVE,
            entityId,
            { active },
            priority
        );
    }
    
    // ========== 动画操作命令 ==========
    
    /**
     * 播放动画
     * @param entityId 实体 ID
     * @param animName 动画名称
     * @param loop 是否循环（默认 false）
     * @param priority 优先级
     */
    static playAnimation(
        entityId: number,
        animName: string,
        loop: boolean = false,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.PLAY_ANIMATION,
            entityId,
            { name: animName, loop },
            priority
        );
    }
    
    /**
     * 停止动画
     */
    static stopAnimation(
        entityId: number,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.STOP_ANIMATION,
            entityId,
            {},
            priority
        );
    }
    
    /**
     * 暂停动画
     */
    static pauseAnimation(
        entityId: number,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.PAUSE_ANIMATION,
            entityId,
            {},
            priority
        );
    }
    
    // ========== Sprite 操作命令 ==========
    
    /**
     * 设置 Sprite 颜色
     * @param entityId 实体 ID
     * @param color 颜色对象或 { r, g, b, a }
     * @param priority 优先级
     */
    static setSpriteColor(
        entityId: number,
        color: Color | { r: number; g: number; b: number; a?: number },
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_SPRITE_COLOR,
            entityId,
            color,
            priority
        );
    }
    
    /**
     * 设置 Sprite 透明度
     * @param entityId 实体 ID
     * @param opacity 透明度 (0-255)
     * @param priority 优先级
     */
    static setSpriteOpacity(
        entityId: number,
        opacity: number,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_SPRITE_OPACITY,
            entityId,
            { opacity },
            priority
        );
    }
    
    // ========== Label 操作命令 ==========
    
    /**
     * 设置 Label 文本
     * @param entityId 实体 ID
     * @param text 文本内容
     * @param priority 优先级
     */
    static setLabelText(
        entityId: number,
        text: string,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_LABEL_TEXT,
            entityId,
            { text },
            priority
        );
    }
    
    /**
     * 设置 Label 颜色
     * @param entityId 实体 ID
     * @param color 颜色对象或 { r, g, b, a }
     * @param priority 优先级
     */
    static setLabelColor(
        entityId: number,
        color: Color | { r: number; g: number; b: number; a?: number },
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_LABEL_COLOR,
            entityId,
            color,
            priority
        );
    }
    
    // ========== 批量操作 ==========
    
    /**
     * 批量设置位置
     * @param entities 实体 ID 和位置的数组
     */
    static batchSetPosition(entities: Array<{ entityId: number; x: number; y: number; z?: number }>): string[] {
        return commandQueue.addCommands(
            entities.map(e => ({
                type: CommandType.SET_POSITION,
                entityId: e.entityId,
                params: { x: e.x, y: e.y, z: e.z || 0 },
                priority: CommandPriority.NORMAL
            }))
        );
    }
    
    /**
     * 批量播放动画
     * @param entities 实体 ID 和动画名称的数组
     */
    static batchPlayAnimation(entities: Array<{ entityId: number; animName: string; loop?: boolean }>): string[] {
        return commandQueue.addCommands(
            entities.map(e => ({
                type: CommandType.PLAY_ANIMATION,
                entityId: e.entityId,
                params: { name: e.animName, loop: e.loop || false },
                priority: CommandPriority.NORMAL
            }))
        );
    }
    
    /**
     * 批量设置可见性
     * @param entityIds 实体 ID 数组
     * @param visible 是否可见
     */
    static batchSetVisible(entityIds: number[], visible: boolean): string[] {
        return commandQueue.addCommands(
            entityIds.map(id => ({
                type: CommandType.SET_VISIBLE,
                entityId: id,
                params: { visible },
                priority: CommandPriority.NORMAL
            }))
        );
    }
    
    // ========== 节点生命周期 ==========
    
    /**
     * 销毁节点
     * @param entityId 实体 ID
     * @param immediate 是否立即销毁
     * @param priority 优先级
     */
    static destroyNode(
        entityId: number,
        immediate: boolean = false,
        priority: CommandPriority = CommandPriority.HIGH
    ): string {
        return commandQueue.addCommand(
            CommandType.DESTROY_NODE,
            entityId,
            { immediate },
            priority
        );
    }
    
    // ========== 特效和音效（占位，需要扩展） ==========
    
    /**
     * 播放特效
     * @param entityId 实体 ID
     * @param effectName 特效名称
     * @param priority 优先级
     */
    static playEffect(
        entityId: number,
        effectName: string,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.PLAY_EFFECT,
            entityId,
            { effectName },
            priority
        );
    }
    
    /**
     * 播放音效
     * @param entityId 实体 ID
     * @param soundName 音效名称
     * @param priority 优先级
     */
    static playSound(
        entityId: number,
        soundName: string,
        priority: CommandPriority = CommandPriority.NORMAL
    ): string {
        return commandQueue.addCommand(
            CommandType.PLAY_SOUND,
            entityId,
            { soundName },
            priority
        );
    }
}

/**
 * 带依赖的命令助手（高级功能）
 */
export class LogicCommandWithDependency {
    /**
     * 设置位置（带依赖）
     */
    static setPosition(
        entityId: number,
        x: number,
        y: number,
        z: number = 0,
        dependencies: string[]
    ): string {
        return LogicCommandHelper.setPosition(
            entityId,
            x,
            y,
            z,
            { dependencies }
        );
    }
    
    /**
     * 播放动画（带依赖）
     */
    static playAnimation(
        entityId: number,
        animName: string,
        loop: boolean = false,
        dependencies: string[]
    ): string {
        return commandQueue.addCommand(
            CommandType.PLAY_ANIMATION,
            entityId,
            { name: animName, loop },
            CommandPriority.NORMAL,
            undefined,
            dependencies
        );
    }
    
    /**
     * 设置颜色（带依赖）
     */
    static setSpriteColor(
        entityId: number,
        color: Color | { r: number; g: number; b: number; a?: number },
        dependencies: string[]
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_SPRITE_COLOR,
            entityId,
            color,
            CommandPriority.NORMAL,
            undefined,
            dependencies
        );
    }
    
    /**
     * 设置文本（带依赖）
     */
    static setLabelText(
        entityId: number,
        text: string,
        dependencies: string[]
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_LABEL_TEXT,
            entityId,
            { text },
            CommandPriority.NORMAL,
            undefined,
            dependencies
        );
    }
    
    /**
     * 显示/隐藏（带依赖）
     */
    static setVisible(
        entityId: number,
        visible: boolean,
        dependencies: string[]
    ): string {
        return commandQueue.addCommand(
            CommandType.SET_VISIBLE,
            entityId,
            { visible },
            CommandPriority.NORMAL,
            undefined,
            dependencies
        );
    }
}

/**
 * 便捷导出（可以直接使用）
 */
export const LogicCmd = LogicCommandHelper;
export const LogicCmdDep = LogicCommandWithDependency;

